package com.ebarlas.fractal;

import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GETFIELD;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.PUTFIELD;

import com.ebarlas.fractal.compile.CompilerUtils;
import com.ebarlas.fractal.compile.Variable;
import com.ebarlas.fractal.util.Complex;

public class FieldAccessVariable extends Variable {
    
    private String name;
    
    public FieldAccessVariable(Complex value, String name) {
        super(value);
        this.name = name;
    }    
    
    public FieldAccessVariable(String name) {
        this(Complex.ZERO, name);
    }

    @Override
    public void compileConstructor(ConstantPoolGen cp, InstructionList il, InstructionFactory factory) {
        String className = factory.getClassGen().getClassName();
        
        // push this
        il.append(InstructionFactory.createThis());
        
        // push value
        CompilerUtils.pushComplexLiteral(cp, il, factory, getValue());
        
        // putfield
        PUTFIELD pf = factory.createPutField(className, name, CompilerUtils.COMPLEX_TYPE);
        il.append(pf);      
    }

    /**
     * Push complex field on to stack
     * Stack: ... -> ..., complex
     */
    @Override
    public void compileExecute(ConstantPoolGen cp, InstructionList il, InstructionFactory factory) {
        String className = factory.getClassGen().getClassName();
        
        // push this
        il.append(InstructionFactory.createThis());        
        
        // getfield
        GETFIELD gf = factory.createGetField(className, name, CompilerUtils.COMPLEX_TYPE);
        il.append(gf);
    }

}
